﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;

namespace CoursePack
{
    [Serializable]
    public class Class
    {
        private string m_StartTime;
        private string m_EndTime;
        private List<DayOfWeek> m_DaysOccurence;             // Monday , Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday

        private string m_Classroom;
        private string m_Section;
        private string m_Teacher;
        private ClassType m_ClassType;

        private string m_Campus;
        /// <summary>
        /// Constructor for a Lecture
        /// </summary>
        /// <param name="_Days">Days of the week the Tut or the Lab occurs</param>
        /// <param name="_Start">Start Time of the class</param>
        /// <param name="_End">End time of the class</param>
        /// <param name="_Section">Section of the class</param>
        /// <param name="_Classroom">Classroom of the class</param>
        /// <param name="_Teacher"></param>
        public Class(ClassType _ClassType, string _Days, string _Start, string _End, string _Section,string _Classroom, string _Teacher)
        {
            this.m_StartTime = _Start;
            this.m_EndTime = _End;
            this.m_Section = _Section;
            this.m_Classroom = _Classroom;
            this.m_ClassType = _ClassType;

            if (_Classroom.Length != 0)
                this.m_Campus = _Classroom[0].ToString();

            this.m_Teacher = _Teacher;

            this.m_DaysOccurence = new List<DayOfWeek>();
            SetDays(_Days);

        }

        /// <summary>
        /// Constructor for a Tutorial or Lab
        /// </summary>
        /// <param name="_Days">Days of the week the Tut or the Lab occurs</param>
        /// <param name="_Start">Start Time of the class</param>
        /// <param name="_End">End time of the class</param>
        /// <param name="_Section">Section of the class</param>
        /// <param name="_Classroom">Classroom of the class</param>
        public Class(ClassType _ClassType, string _Days, string _Start, string _End, string _Section, string _Classroom)
        {
            this.m_StartTime = _Start;
            this.m_EndTime = _End;
            this.m_Section = _Section;
            this.m_Classroom = _Classroom;
            this.m_ClassType = _ClassType;

            if (_Classroom.Length != 0)
                this.m_Campus = _Classroom[0].ToString();
            this.m_Teacher = "";

            this.m_DaysOccurence = new List<DayOfWeek>();
            SetDays(_Days);

        }

        private void SetDays(string _Days)
        {
            foreach (char c in _Days)
            {
                switch (c)
                {
                    case 'M' :
                        m_DaysOccurence.Add(DayOfWeek.Monday);
                        break;
                    case 'T':
                        m_DaysOccurence.Add(DayOfWeek.Tuesday);
                        break;
                    case 'W':
                        m_DaysOccurence.Add(DayOfWeek.Wednesday);
                        break;
                    case 'J':
                        m_DaysOccurence.Add(DayOfWeek.Thursday);
                        break;
                    case 'F':
                        m_DaysOccurence.Add(DayOfWeek.Friday);
                        break;
                    case 'S':
                        m_DaysOccurence.Add(DayOfWeek.Saturday);
                        break;
                    case 'D':
                        m_DaysOccurence.Add(DayOfWeek.Sunday);
                        break;
                }
            }
        }

        public int ClassConflicts(Class _C2)
        {
            int conflictscount = 0;

            foreach(DayOfWeek day in _C2.DaysOfTheWeek)
            {
                if (this.DaysOfTheWeek.Contains(day))
                {
                    if (
                    ((this.StartDate.TimeOfDay >= _C2.StartDate.TimeOfDay) && (this.StartDate.TimeOfDay < _C2.EndDate.TimeOfDay) ||
                    ((this.EndDate.TimeOfDay > _C2.StartDate.TimeOfDay) && (this.EndDate.TimeOfDay <= _C2.EndDate.TimeOfDay))))
                    {
                        conflictscount++;
                    }
                }
            }



            return conflictscount;
        }

        #region Accessors
        public DateTime StartDate
        {
            get { return DateTime.Parse(this.m_StartTime); }
        }

        public DateTime EndDate
        {
            get { return DateTime.Parse(this.m_EndTime); }
        }

        public int StartTime
        {
            get {
                    string b = string.Empty;
                    int val = 0;
                    for (int i=0; i< this.m_StartTime.Length; i++)
                    {
                        if (Char.IsDigit(this.m_StartTime[i]))
                            b += this.m_StartTime[i];
                    }
                    if (b.Length > 0)
                        val = int.Parse(b);

                return val;
            
            }
            
        }
        
        public int EndTime
        {
            get
            {
                    string b = string.Empty;
                    int val = 0;
                    for (int i=0; i< this.m_EndTime.Length; i++)
                    {
                        if (Char.IsDigit(this.m_EndTime[i]))
                            b += this.m_EndTime[i];
                    }
                    if (b.Length > 0)
                        val = int.Parse(b);
                            ;
                return val;
            }
        }

        public string Days
        {
            get { return Tools.DaysToDays(this.m_DaysOccurence); }
        }

        public string Section
        {
            get { return this.m_Section; }
        }

        public string Campus
        {
            get { return this.m_Campus; }
        }

        public override string ToString()
        {
            return this.TypeOfClass + "  " + this.m_Section +  " |" + this.Days + "| " + this.m_StartTime + " - " + this.m_EndTime;
        }

        public string TypeOfClass
        {
            get {
                switch (m_ClassType)
                {
                    case ClassType.Lecture:
                        return "Lect";
                    case ClassType.Tutorial:
                        return "Tut";
                    case ClassType.Lab:
                        return "Lab";
                    default :
                        return "";
                }
            }
        }

        public List<DayOfWeek> DaysOfTheWeek
        {
            get { return this.m_DaysOccurence; }
        }

        public string Professor
        {
            get {
                return this.m_Teacher;
            }
        }
        public string ProfessorII
        {
            get
            {
                string[] tab = m_Teacher.Split(' ');
                string ln = tab[0];
                string fn = tab[1];

                return fn + " " + ln;
            }
        }
        #endregion
    }


}
